package br.com.beans;

import java.util.List;
import java.util.Set;
import java.util.TreeSet;

import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;

import br.com.dao.EspecialidadeDAO;

/** Classe que representa uma especialidade medica */
@Entity
@Table(name="tb_especialidade")
public class Especialidade {

	/** Codigo da especialidade */
	@Id
	@GeneratedValue(strategy = GenerationType.AUTO)
	@Column(nullable=false)
	private int codigo;

	/** Descricao da especialidade */
	@Column(length=50,nullable=false)
	private String descricao;
	
	/** Lista de medicos que atendem a essa especialidade */
	@OneToMany(cascade=CascadeType.ALL,mappedBy="especialidade",fetch=FetchType.EAGER)
	private Set<Medico> medicos = new TreeSet<Medico>();
	
	/** Construtor padrao */
	public Especialidade() {}

	/** Construtor de copia */
	public Especialidade(Especialidade especialidade) {
		copiar(especialidade);
	}

	/** Limpa todos atributos. */
	public void limpar() {
		setCodigo(0);
		setDescricao(null);
		medicos.clear();
	}

	/** Copia atributos de outro objeto.
	 *  @param obj Objeto a ser copiado */
	public void copiar(Especialidade obj) {
		if (obj != null) {
			//codigo    = obj.codigo;
			descricao = obj.descricao;
			medicos.clear();
			medicos.addAll(obj.medicos);
		} else {
			limpar();
		}
	}
	
	/** Cadastra uma especialidade. */
	public void cadastrar() {
		EspecialidadeDAO especialidadeDAO = new EspecialidadeDAO();
		FacesMessage facesMessage = null;  

		if (especialidadeDAO.inserir(this)) {
			facesMessage = new FacesMessage("Especialidade adicionada com sucesso.",null);  
			limpar();
		} else {
			facesMessage = new FacesMessage("Erro ao adicionar especialidade.",null);  
		}
		FacesContext.getCurrentInstance().addMessage(null,facesMessage);  
	}
	
	/** Remove uma especialidade. */
	public void remover() {
		EspecialidadeDAO especialidadeDAO = new EspecialidadeDAO();
		FacesMessage facesMessage = null;  

		if (especialidadeDAO.excluir(getCodigo())) {
			facesMessage = new FacesMessage("Especialidade removida com sucesso.",null);  
		} else {
			facesMessage = new FacesMessage("Erro ao remover especialidade.",null);  
		}
		limpar();
		FacesContext.getCurrentInstance().addMessage(null,facesMessage);  
	}
	
	/** Retorna lista de especialidades.
	 *  @return Lista de especialidades. */
	public List<Especialidade> getLista() {
		EspecialidadeDAO especialidadeDAO = new EspecialidadeDAO();
		return especialidadeDAO.listar();
	}
	
	/** Retorna lista de descricoes de especialidades.
	 *  @return Lista de descricoes de especialidades. */
	public Set<String> getListaDescricao() {
		EspecialidadeDAO especialidadeDAO = new EspecialidadeDAO();
		Set<String> resultado = new TreeSet<String>();

		List<Especialidade> especialidadeList = especialidadeDAO.listar();
		if (especialidadeList != null) {
			for (Especialidade especialidade : especialidadeList){
				resultado.add(especialidade.getDescricao());
			}
		}
		return resultado;
	}
	
	/** Retorna uma lista de nomes de medicos, para esta especialidade.
	 * @return Lista de nomes de medicos. */
	public Set<String> getListaMedicos() {
		EspecialidadeDAO especialidadeDAO = new EspecialidadeDAO();
		Set<String> resultado = new TreeSet<String>();

		Especialidade especialidadeObj = especialidadeDAO.localizar(getDescricao());
		if (especialidadeObj != null) {
			for (Medico medicoObj : especialidadeObj.getMedicos()) {
				resultado.add(medicoObj.getUsuario().getNome());
			}
		}
		return resultado;
	}
	
	public int getCodigo() {
		return codigo;
	}

	public void setCodigo(int codigo) {
		this.codigo = codigo;
	}

	public String getDescricao() {
		return descricao;
	}

	public void setDescricao(String descricao) {
		this.descricao = descricao;
	}

	public void setMedicos(Set<Medico> medicos) {
		this.medicos = medicos;
	}

	public Set<Medico> getMedicos() {
		return medicos;
	}

}
